﻿;;#SingleInstance, force
SetCapsLockState, AlwaysOff
SetScrollLockState, AlwaysOff
DllCall("SetThreadDpiAwarenessContext", "ptr", -3, "ptr") ;;次屏幕会出现问题，所以需要添加该语句解决，可以很好的解决问题，就喜欢这种简洁好用的语句
;; Use Keyboard to control mouse 
speed = 50
CapsLock & 8::speed := 10
CapsLock & 9::speed := 40
CapsLock & 0::speed := 200
CapsLock & j::MouseMove, 0, -speed, 2, R  ; Win+UpArrow hotkey => Move cursor upward
CapsLock & k::MouseMove, 0, speed, 2, R  ; Win+DownArrow => Move cursor downward
CapsLock & h::MouseMove, -speed, 0, 2, R  ; Win+LeftArrow => Move cursor to the left
CapsLock & l::MouseMove, speed, 0, 2, R  ; Win+RightArrow => Move cursor to the right
CapsLock & n::Send {Click Left}
CapsLock & m::Send {Click Right}
CapsLock & u::Send {WheelUp}
CapsLock & [::Send, +{WheelUp}
CapsLock & i::Send {WheelDown}
CapsLock & ]::Send, +{WheelDown}
#o::Suspend  ; Win+o Suspend
CapsLock & o::Reload  ; autohotkey Reload

;;换一种思路，不通过激活场景，直接使用CapsLock键进行映射移动光标，因为原来的按键其实是足够的。
CapsLock & a::Left
CapsLock & s::Down
CapsLock & w::Up
CapsLock & d::Right
CapsLock & f::Home
CapsLock & g::End
CapsLock & Up::#PgUp
CapsLock & Down::#PgDn
;;mouse follow actived Win
CapsLock & p:: 
{			Sleep, 10
			CoordMode, Mouse, Screen
			WinGetPos, wx, wy, width, height, A
; puts the cursor in the upper right corner of the active window, tweak to your needs
			mx := Round(wx + width * 0.65)
			my := Round(wy + height * 0.5)
			DllCall("SetCursorPos", int, mx, int, my)
}
return
;; #Include D:\personal\software\ahkscript\switchIME.ahk
;; add hotkey replace evernote hotkey
;CapsLock & =::
;send ("!^n")
;return
;CapsLock & b:: +^l
CapsLock & F2:: 
; 激活Microsoft Edge窗口并通过一系列触发动作实现快速切换workspace的效果
IfWinExist, ahk_exe msedge.exe
{
    WinActivate ; 使用IfWinExist找到的窗口
    Sleep, 100 ; 等待100毫秒让窗口激活

    ; 获取窗口的位置和尺寸
    WinGetPos, X, Y, Width, Height, ahk_exe msedge.exe
    ; 将鼠标移动到窗口的左上角
    ; 假设你想要将鼠标移至距离窗口边缘10像素的位置
    MouseMove, X + 80, Y + 10, 0
    Click
    Sleep, 300
    ;按下三次Tab键
    Send,{Tab 3}
}
return

;; 使用win + J 替换Win+Tab的功能
;#j:: #Tab
;; 使用win + K切换焦点到下一个窗口
;#k:: !+Tab
;; Hack win+s replace with evertything
#s::
Run "C:\Program Files\Everything\Everything.exe" 
return
;;快速切换程序的焦点,这个也不成我服了今天 服了，原来是程序没用对，autohotkey自带了winspy然后测出来的值不一样，我的老天爷
;;后来又可以了，有时候真的是搞不懂，是不是被玩了。。。
CapsLock & 1:: 

IfWinExist ahk_exe  Code.exe
{
	WinActivate
}
return
CapsLock & 2:: 

IfWinExist ahk_exe  msedge.exe
{
	WinActivate
}
return
CapsLock & 3:: 
IfWinExist ahk_class WeChatMainWndForPC  
{
	WinActivate
}
Return
CapsLock & 4:: 
IfWinExist ahk_exe  Feishu.exe
{
	WinActivate
}
return

CapsLock & 5:: 
IfWinExist ahk_class CabinetWClass
{
	WinActivate
}
return
;;添加快捷键映射大写+-号为control键的中英文，主要是用在映射ctrl+space的映射。
CapsLock & -::^Space
;; 将win+m键替换成单个窗口最小化，避免全部最小化，毕竟又不能全部恢复，其实没啥用。如果是用来看桌面，那只要win+d就可以了，不用那么复杂。
#m::#Down
;;映射文件浏览器下使用vim键位
IfWinActive,ahk_exe explorer.exe 
{
	!j::Send {Up}
	!k::Send {Down}
	!l::Send {AltDown}{Up}{AltUp} ;;回到父级菜单
	!h::Send {AltDown}{Left}{AltUp} ;;后退
}
Return
;;双击两次Capslock键进行大小写切换 结果是没有触发两次，只是触发了一次，也是比较奇葩，但是无所谓了，这样反而更好用，也没有影响到其他的快捷键触发
; 设置 CapsLock 键为触发键。
$CapsLock::
    ; 记录第一次按下 CapsLock 的时间
    KeyWait, CapsLock
    ; 如果在 500 毫秒内再次按下 CapsLock，则执行下面的代码
    if (A_TimeSinceThisHotkey < 10) {
        ; 这里替换为你想要映射的快捷键
        Send {LWinDown}{Space}{LWinUp}
        ; 等待释放 CapsLock 键
        KeyWait, CapsLock
    }
return
;;通过capslock+e键触发powertoys并输入<和空格，这样就避免了每次都要输入新的内容才能快速的切换窗口，这个程序有一个问题，就是如果输入法状态是中文，输入的内容也是中文，有没有什么办法让其输入的是不受输入法状态影响的字符，现在monica给出的建议并不能解决我的问题。
CapsLock & e:: 
{
 #InputLevel Play
 Send {AltDown}{Space}{AltUp}
 Send {Blind}{Text}< 
 return
}
;; 模拟dwm中将当前窗口变成主窗口的操作 另外有个问题，变到新的位置倒是很容易，但是怎么回到原来的位置呢？这个要实现起来就比较麻烦了，首先要识别一个原始的状态，如果这个原始状态存在，在触发热键时要识别这个原始状态，原始状态存在则恢复到原始状态，同时重置原始状态为0，如果没有原始状态则放置到master的位置,并新增一个原始状态，同时回传回全局变量。实现的思路是这样的，但是具体要在autohotkey中怎么去实现，这个我得想想
; 设置一个热键，例如：CapsLock+enter 基本上是实现了想要的功能，但是有很多的bug，不过暂时还能用，具体的bug看下边的说明
global gk := 0
global origin_x := 0
global origin_y := 0
global origin_width := 0
global origin_height := 0
CapsLock & Enter:: SnapWindowToMonitor() 
;;经过改进，已经可以实现不同窗口也能恢复到原位，但是还是有问题，就是老窗口会恢复到新窗口的原位，哈哈哈，这个程序也写工程越大了，恐怕是还得判断空值 通过获得和改写wintitle已经可以实现想要的功能，但是还是有bug就是必须要让经过居中的窗口回到原位之后，在进行下一次的操作，否则就会出现问题，这个问题暂时没有办法解决
SnapWindowToMonitor() {
	WinGet, active_id, ID, A
	WinGetPos, X, Y, Width, Height, ahk_id %active_id%
	WinGetTitle, gk , A 
	origin_gk := gk
	screen_width := A_ScreenWidth
    screen_height := A_ScreenHeight
    newWidth := screen_width * 0.7
    newHeight := screen_height * 0.7
	new_x := (screen_width - newWidth) / 2
    new_y := (screen_height - newHeight) / 2
	If (gk = "marker")
	{
		WinMove,  ahk_id %active_id%,, %origin_x%, %origin_y%,%origin_width%,%origin_height% ;;把窗口恢复到原位
		gk := %origin_gk%
		WinSetTitle, A,,gk 	
		}
	Else
	{
	origin_x := X 
	origin_y := Y
	origin_width := Width
	origin_height := Height
    WinMove, "ahk_id %active_id%", , %new_x%, %new_y% ,%newWidth%,%newHeight% ; 将窗口移动到屏幕中间
	WinSetTitle, A,, marker
		}
    }
Return

; CapsLock+F1 : open highlighted text in browser and do google search / visit site (if it's url)


; run script as admin (reload if not as admin) 
if not A_IsAdmin
{
   Run *RunAs "%A_ScriptFullPath%"  ; Requires v1.0.92.01+
   ExitApp
}

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance Force
SetTitleMatchMode 2


CapsLock & F1::
MyClip := ClipboardAll
Clipboard = ; empty the clipboard
Send, ^c
ClipWait, 2
if ErrorLevel  ; ClipWait timed out.
{
    return
}
if RegExMatch(Clipboard, "^[^ ]*\.[^ ]*$")
{
    Run "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" %Clipboard%
}
else  
{
    ; Modify some characters that screw up the URL
    ; RFC 3986 section 2.2 Reserved Characters (January 2005):  !*'();:@&=+$,/?#[]
    StringReplace, Clipboard, Clipboard, `r`n, %A_Space%, All
    StringReplace, Clipboard, Clipboard, #, `%23, All
    StringReplace, Clipboard, Clipboard, &, `%26, All
    StringReplace, Clipboard, Clipboard, +, `%2b, All
    StringReplace, Clipboard, Clipboard, ", `%22, All
    Run % "https://www.google.com/search?hl=en&q=" . clipboard ; uriEncode(clipboard)
}
Clipboard := MyClip
return

; Handy function.
; Copies the selected text to a variable while preserving the clipboard.
GetText(ByRef MyText = "")
{
   SavedClip := ClipboardAll
   Clipboard =
   Send ^c
   ClipWait 0.5
   If ERRORLEVEL
   {
      Clipboard := SavedClip
      MyText =
      Return
   }
   MyText := Clipboard
   Clipboard := SavedClip
   Return MyText
}

; Pastes text from a variable while preserving the clipboard.
PutText(MyText)
{
   SavedClip := ClipboardAll 
   Clipboard =              ; For better compatability
   Sleep 20                 ; with Clipboard History
   Clipboard := MyText
   Send ^v
   Sleep 100
   Clipboard := SavedClip
   Return
}
; 定义一个变量来跟踪模式是否激活
isModeActive := false
; 监听 CapsLock + F3 的组合键
CapsLock & F3:: ; '&'用于组合键
    ; 切换模式的激活状态
    isModeActive := !isModeActive
    if (isModeActive) {
        TrayTip, Mode Active, The key remapping mode is now active., , 1
    } else {
        TrayTip, Mode Inactive, The key remapping mode is now inactive., , 1
    }
return
; 如果模式激活，则将按键映射到相应的数字
#If (isModeActive)
    q::Send, 1
    w::Send, 2
    e::Send, 3
    a::Send, 4
    s::Send, 5
    d::Send, 6
    z::Send, 7
    x::Send, 8
    c::Send, 9
#If ; 结束条件指令块
; 关闭所有组内的窗口
CapsLock & F4::
    GroupAdd, MyFolder, ahk_class CabinetWClass ; 将文件夹浏览器窗口添加到组MyFolderGroup
    WinClose, ahk_group  MyFolder ; 关闭MyFolderGroup组中的所有窗口
return
#IfWinActive, ahk_exe Code.exe
^-:: 
    ruanjian := "D:\\personal\\software\\sioyek-release-windows-portable\\sioyek-release-windows\\sioyek.exe"
    FileToopen := "D:\\personal\\software\\tips\\vscode-keyboard-shortcuts-windows.pdf"
    Run,%ruanjian% %FileToopen%
return
#IfWinActive

;;设置CapsLock+/为全局的触发按键提示按钮，并且把所有的已经自定义的快捷按钮显示出来。
ShowArrayValuesWithCombinedTooltip(array)
{
    combinedValues := ""  ; 用于存储组合后的数值信息
    for rowIndex, row in array  ; 遍历二维数组中的每一行
    {
        value1 := row.1  ; 获取当前行中的第一个数值
        value2 := row.2  ; 获取当前行中的第二个数值
        combinedValues .= "Hotkey is " . value1 . ",Use to " . value2 . "`n"  ; 将数值信息组合添加到列表中
    }
    MsgBox,  %combinedValues%  ; 在屏幕上显示组合后的数值信息
;    Sleep, 5000  ; 显示提示信息 5 秒钟
;    ToolTip  ; 清除提示信息
}

; 调用定义的函数并传入一个二维数组
CapsLock & /::
    my2DArray := [["lead+F1", "Searching the selected text"], ["Lead+F2", "Switching the Microsoft Edge Workspace"], ["Lead+F3", "Active/Inactive Numpad of qweasdzxc"], ["Lead+F4", "Close all File exploerer"], ["Lead+Space", "Modify selected text such as add quoto or brasket"], ["lead+1", "Activate Vscode"], ["Lead+2", "Activate Edge"], ["Lead+3", "Activate Wechat"], ["Lead+4", "Activate Feishu"], ["Lead+Enter", "Put the Windows to Screen Center"], ["Lead+-", "Switch Input EN/CN"], ["Lead+e", "Use powertoys to switch apps"], ["Lead+Q", "SwitchBetween Group"], ["Lead+up or down", "Simulated win+PgUp or PgDn"], ["Lead+r", "switch capslock state"], ["Lead+,", "switch screen left"], ["Lead+.", "switch screen right"], ["Lead+t", "movemouse to input value"]]  ; 示例二维数组
    ShowArrayValuesWithCombinedTooltip(my2DArray)  ; 调用 ShowArrayValuesWithCombinedTooltip 函数并传入二维数组
return
CapsLock & q::
    Getgroup()
    Switch GetActiveWindowGroup(){
        case "Browsers": GroupActivate, netbrowser, R
        case "Myfolder": GroupActivate, myexploer, R
        case "Myeditor": GroupActivate, myeditor, R
        Default: GroupDeactivate, Combinegroup, R
    }
return
#j::
{
    Getgroup()
    GroupActivate, Combinegroup , R
}
return
#k::
{
    Getgroup()
    GroupDeactivate, Combinegroup , R
}
GetActiveWindowGroup() {
   Return WinActive("ahk_group netbrowser") ? "Browsers" : WinActive("ahk_group myexploer") ? "Myfolder" : WinActive("ahk_group myeditor") ? "Myeditor" : ""
}
Getgroup(){
GroupAdd, netbrowser, ahk_exe msedge.exe
GroupAdd, myexploer, ahk_class CabinetWClass
GroupAdd, netbrowser, ahk_exe Code.exe
GroupAdd, myeditor, ahk_exe WeChat.exe
GroupAdd, myeditor, ahk_exe WXWork.exe
GroupAdd, Combinegroup, ahk_group netbrowser 
GroupAdd, Combinegroup, ahk_group myexploer 
GroupAdd, Combinegroup, ahk_group myeditor 
}
return


; 设置CapsLock+空格为快捷键触发器
CapsLock & Space::
    ClipWait, 1 ;;一开始就监控剪贴板
    SendInput, ^c
    ; 显示提示信息但不改变焦点
    ToolTip, 按下k选中的内容添加引号。`n按下j选中的内容添加"()"。`n按下l选中的内容添加"{}"。`n按下o添加"[]"。`n按下s打开提示词文本"[]"。
    ; 等待用户输入
    Input, UserInput, L1 T5  ; 等待一个字符的输入，或者5秒超时
    ; 根据输入执行相应操作
    if (UserInput = "k")
    {
        QuoteText()
    }
    else if (UserInput = "j")
    {
        BracketText()
    }
    else if (UserInput = "l")
    {
        BigBracketText()
    }
    else if (UserInput = "o")
    {
        SquareBracketText()
    }
    else if (UserInput = "s")
    {
       ; run "C:\Program Files\Sublime Text\sublime_text.exe" "D:\personal\note\pha-name.md"
        run "C:\Users\linco\AppData\Local\Programs\Microsoft VS Code\Code.exe" "D:\personal\note\pha-name.md"
    }
    ; 清除提示信息
    ToolTip
return
; 给选中的文本添加双引号
QuoteText() {
    ModifySelectedText("""", """")
}

; 给选中的文本添加括号
BracketText() {
    ModifySelectedText("(", ")")
}
;添加大括号
BigBracketText() {
    ModifySelectedText("{", "}")
}
;添加方括号
SquareBracketText() {
    ModifySelectedText("[", "]")
}
; 文本修改函数
ModifySelectedText(prefix, suffix) {
   ; 修改剪贴板内容
    clipboard := prefix . clipboard . suffix
    ; 等待一小段时间以确保剪贴板内容更新
    Sleep, 100
    ; 粘贴修改后的文本
    SendInput, ^v
}
; 切换 CapsLock 状态
CapsLock & r::
    If GetKeyState("CapsLock", "T") = 1
        SetCapsLockState, AlwaysOff
    Else
        SetCapsLockState, AlwaysOn
Return

;输入坐标移动鼠标
; 创建热键 CapsLock + T
CapsLock & t::
CoordMode,  Mouse, Screen
InputBox, CoordInput, Enter Coordinates, Enter x and y coordinates 
if ErrorLevel
    return
; 提取用户输入的 x 和 y 值
StringSplit, Coords, CoordInput, %A_Space%
; 移动鼠标光标到指定的屏幕坐标位置
MouseMove, % Coords1, % Coords2
return
;用lead+句号进行显示屏之间的切换
; 获取系统显示器数量
; 创建热键 CapsLock + .  Capslock +,用于切换屏幕

CapsLock & .::
CoordMode,  Mouse, Screen
SysGet, M1, Monitor, 1
SysGet, M2, Monitor, 2
SysGet, M3, Monitor, 3
 MouseGetPos, mouseX, mouseY
  if (mouseX >= M2Left && mouseX <= M2Right && mouseY >= M2Top && mouseY <= M2Bottom) {
    MouseMove, (M1Left + M1Right)//2, (M1Top + M1Bottom)//2
  }
  else if (mouseX >= M1Left && mouseX <= M1Right && mouseY >= M1Top && mouseY <= M1Bottom) {
    MouseMove, (M3Left + M3Right)//2, (M3Top + M3Bottom)//2
  }
  else if (mouseX >= M3Left && mouseX <= M3Right && mouseY >= M3Top && mouseY <= M3Bottom) {
    MouseMove, (M2Left + M2Right)//2, (M2Top + M2Bottom)//2
  }
  MouseGetPos,,, HoverWindow
  WinActivate, ahk_id %HoverWindow%
Return

CapsLock & ,:: ;mouse cursor to the center of secondary monitor
CoordMode,  Mouse, Screen
SysGet, M1, Monitor, 1
SysGet, M2, Monitor, 2
SysGet, M3, Monitor, 3
  MouseGetPos, mouseX, mouseY
  if (mouseX >= M2Left && mouseX <= M2Right && mouseY >= M2Top && mouseY <= M2Bottom) {
    MouseMove, (M3Left + M3Right)//2, (M3Top + M3Bottom)//2
  }
  else if (mouseX >= M1Left && mouseX <= M1Right && mouseY >= M1Top && mouseY <= M1Bottom) {
    MouseMove, (M2Left + M2Right)//2, (M2Top + M2Bottom)//2
  }
  else if (mouseX >= M3Left && mouseX <= M3Right && mouseY >= M3Top && mouseY <= M3Bottom) {
    MouseMove, (M1Left + M1Right)//2, (M1Top + M1Bottom)//2
  }
  MouseGetPos,,, HoverWindow
  WinActivate, ahk_id %HoverWindow%
Return
